
import sys
sys.path += ['.']


__author__="raeken"
__date__ ="$09.08.2009 20:37:22$"

if __name__ == "__main__":
    pass

# nehe und bresenham

from OpenGL.GL import *
from OpenGL.GLUT import *
from OpenGL.GLU import *

#from OpenGL.WGL import *

from random import *
from Image import *

import sys
import math
import time
import ImageDraw

def s(speed):
    return speed/10

class ApplicationGL():
    def __init__(self):

        glutInit(())
        glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE | GLUT_ALPHA | GLUT_DEPTH)

        glutInitWindowSize(640, 480)
        glutInitWindowPosition(0, 0)
        window = glutCreateWindow("Wormgame")

        glutDisplayFunc (self.draw)
        glutIdleFunc(self.draw)
        glutReshapeFunc(self.resize)

        glutKeyboardFunc (self.keyDown())
        glutKeyboardUpFunc(self.keyUp())

        glShadeModel(GL_SMOOTH)
        glClearColor(0.0,0.0,0.0,0.0)
        glClearDepth(1.0)
        glHint(GL_PERSPECTIVE_CORRECTION_HINT,GL_NICEST)
        glHint(GL_POINT_SMOOTH_HINT,GL_NICEST)
        glEnable(GL_TEXTURE_2D)

        glEnable(GL_DEPTH_TEST)
        glDepthFunc(GL_LESS)

        glMatrixMode(GL_MODELVIEW)

        glOrtho( 0.0, 640.0, 0.0, 480.0, 1.0, 5.0)

        glutMainLoop()



    def draw(self):
        pass

    def keyDown(self):
        pass

    def keyUp(self):
        pass

    def resize(self,width,height):
        pass

class BaseObject():
    def __init__(self, position, master):
        self.master = master
        self.position = position
        self.x = position.x
        self.y = position.y

class TexturedObject():
    def __init__(self):
        self.textured = True
        self.texture = 0

    def loadTexture(self,path):
        global texId
        texId = texId + 1
        #self.texture = texId
        tex = texId
        self.image_data = open(path)
        ix = self.image_data.size[0]
        iy = self.image_data.size[1]
        self.width = ix
        self.height = iy
        self.image_data_raw = self.image_data.tostring("raw", "RGBX", 0, 1)

        glBindTexture(GL_TEXTURE_2D, tex)
        #glBlendFunc(GL_SRC_ALPHA,GL_ONE)
        glPixelStorei(GL_UNPACK_ALIGNMENT,1)
        glTexImage2D(GL_TEXTURE_2D, 0, 3, self.width, self.height, 0, GL_RGBA, GL_UNSIGNED_BYTE, self.image_data_raw)
        glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP)
        glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP)
        glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT)
        glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT)
        glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST)
        glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST)
        #glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL)

        return tex


class RelativePositionObject():
    """
    anders loesen: BaseClass -> HudElement
    """
    def __init__(self,parent):
        self.parent = parent

    def update(self):
        pass

    def draw(self):

        angle = math.radians((self.parent.direction + self.parent.angle_aim)*(self.parent.direction/abs(self.parent.direction)))

        display_position = Vector(math.cos(angle),math.sin(angle)) * 100

        glDisable(GL_TEXTURE_2D)
        #glBindTexture(GL_TEXTURE_2D, 1)
        glBegin(GL_QUADS)                   # Start drawing a 4 sided polygon
        #glColor3f(self.parent.color[0],self.parent.color[1],self.parent.color[2])
        glTexCoord2f(0.0, 1.0);
        glVertex3f(self.parent.x+display_position.x-5, self.parent.y+display_position.y+5, 0)              # Top Left
        glTexCoord2f(0.0, 0.0);
        glVertex3f(self.parent.x+display_position.x-5, self.parent.y+display_position.y-5, 0)                # Bottom Left
        glTexCoord2f(1.0, 0.0);
        glVertex3f(self.parent.x+display_position.x+5, self.parent.y+display_position.y-5, 0)              # Bottom Right
        glTexCoord2f(1.0, 1.0);
        glVertex3f(self.parent.x+display_position.x+5, self.parent.y+display_position.y+5, 0)            # Top Right
        glEnd()

class BulletObject(BaseObject):
    def __init__(self,position):
        pass

class MatchController():
    def __init__(self):
        self.name = "mc"
        self.rounds = 1
        self.players = list()

    def newMatch(self):
        self.terrain = TerrainController()
        self.round = SpaceGame(self.terrain)

    def loop(self):
        #self.terrain.draw()
        self.round.loop()
        #print "terrain draw"

class RoundController():
    """
    Eine Runde des Spiels,
    hier findet das eigentliche Spiel statt
    """
    def __init__(self,map):
        self.terrain = map
        self.record = 0
        self.lastPath = 0
        #self.mc = parent
        self.players = list()
        self.objects = list()




        cforces = list()
        dforces = list()

        gravity = -0.1
        #angle_gravity = math.radians(90)
        angle_gravity = math.radians(90)
        force_gravity = Vector(math.cos(angle_gravity),math.sin(angle_gravity)) * gravity

        planet_one = GravitationalObject(Vector(340,220),self,0.2)


         #planets map:
        planet_1 = GravitationalObject(Vector(50,54),self,0.2)
        planet_2 = GravitationalObject(Vector(219,175),self,0.2)
        planet_3 = GravitationalObject(Vector(336,367),self,0.2)
        planet_4 = GravitationalObject(Vector(573,278),self,0.2)
        planet_5 = GravitationalObject(Vector(833,394),self,0.2)
        planet_6 = GravitationalObject(Vector(947,117),self,0.2)
        planet_7 = GravitationalObject(Vector(1339,231),self,0.4)


        dforces.append(planet_1)
        dforces.append(planet_2)
        dforces.append(planet_3)
        dforces.append(planet_4)
        dforces.append(planet_5)
        dforces.append(planet_6)
        dforces.append(planet_7)



        #cforces.append(force_gravity)
        #dforces.append(planet_one)

        ## negative:
        #negative_planet = GravitationalObject(Vector(400,300),self,-0.2)
#        negative_planet = GravitationalObject(Vector(1065,1056),self,-0.5)
#        dforces.append(negative_planet)
#        self.objects.append(negative_planet)

        char = Character(Vector(600,400),self,cforces,dforces)
        #char = Character(Vector(1000,1000),self,cforces,dforces)
        char.terrain = map

#        self.objects.append(planet_1)
#        self.objects.append(planet_2)
#        self.objects.append(planet_3)
#        self.objects.append(planet_4)
#        self.objects.append(planet_5)
#        self.objects.append(planet_6)
#        self.objects.append(planet_7)

        #cross = RelativePositionObject(char)

        #self.objects.append(cross)
        self.players.append(char)
        keys.target = char

        self.particleEmitter = ParticleEmitter(Vector(200,200),char)

        self.registerUpdate(self.particleEmitter)

    def registerUpdate(self,object):
        pass
        #self.objects.append(object)

    def loop(self):

        global fps

        for player in self.players:
            self.lastPath = player.pathLength

        if (self.lastPath > self.record):
            self.record = self.lastPath

        szTitle = "%d FPS, Letzter Pfad: %d, Rekord: %d" % (fps,self.lastPath,self.record);
        glutSetWindowTitle(szTitle)

        #self.terrain.draw()
        keys.target.processKeys()

        self.particleEmitter.update(100)
        self.particleEmitter.draw()

        for p in self.players:
            p.update()
            p.draw()
        for o in self.objects:
            o.update()
            o.draw()



class KeyController():
    """
    Verwaltet den Keystatus im target-Objekt
    """
    def __init__(self,target = False):
        self.targets = list()
        self.target = target
        self.targetMap = {}
        self.registeredKeys = list()

    def keyDown(self,key):
        if (key in self.registeredKeys):
            self.targetMap[key].keys[key] = True
            #print "keyDown: ", key ,": ", self.target.keys[key]

    def keyUp(self,key):
        if (key in self.registeredKeys):
            self.targetMap[key].keys[key] = False

    def registerKeys(self,target,keys):
        for key in keys:
            self.targetMap[key] = target
            self.registeredKeys.append(key)


class KeyControledObject():
    """
    Tastaturbelegung Player
    """
    def __init__(self):
        self.keys = {"b":False,"a":False,"d":False,"w":False,"s":False,"j":False,"k":False,"6":False,"4":False,"0":False," ":False}
        self.power = 0

    def processKeys(self):
        if self.keys["a"] == True:
            self.direction = 90
            self.move()
            winkel = self.angle - math.radians(90)
            self.velocity = self.velocity + Vector(math.cos(winkel),math.sin(winkel)) * 0.2
        if self.keys["d"] == True:
            self.direction = -90
            self.move()
            winkel = self.angle + math.radians(90)
            self.velocity = self.velocity + Vector(math.cos(winkel),math.sin(winkel)) * 0.2
        if self.keys["w"] == True:
            self.angle_aim -= s(5.0)
            #self.velocity = self.velocity * 1.01
        if self.keys["s"] == True:
            self.angle_aim += s(5.0)
            #self.velocity = self.velocity * 0.9
        if self.keys["j"] == True:
            self.keys["j"] = False
            self.jump()
        if self.keys["k"] == True:
            self.keys["k"] = False
        if self.keys[" "] == True:
            self.power = self.power + s(2.0)
            #self.shoot()
        if self.power > 0 and self.keys[" "] == False:
            self.shoot()
            self.power = 0
        if self.keys["4"] == True:
            self.direction = 90
            self.move()
            winkel = self.angle - math.radians(90)
            self.velocity = self.velocity + Vector(math.cos(winkel),math.sin(winkel)) * 0.2
        if self.keys["6"] == True:
            self.direction = -90
            self.move()
            winkel = self.angle + math.radians(90)
            self.velocity = self.velocity + Vector(math.cos(winkel),math.sin(winkel)) * 0.2
        if self.keys["0"] == True:
            self.keys["0"] = False
            self.jump()

    # in ein anderes Objekt
    def getVelocity(self):
        velocity = Vector(0,0)
        if self.constant_forces:
            for force in self.constant_forces:
                velocity += force
        if self.dynamic_forces:
            for source in self.dynamic_forces:
                tforce = source.calculate_gravity(Vector(self.x,self.y))
                velocity += tforce*-40
        return velocity

    def getExpVelocity(self):
        maxtforce = Vector(0,0)
        velocity = Vector(0,0)
        if self.constant_forces:
            for force in self.constant_forces:
                velocity += force
        if self.dynamic_forces:
            for source in self.dynamic_forces:
                tforce = source.calculate_gravity(Vector(self.x,self.y))
                if tforce > maxtforce:
                    maxtforce = tforce
                #velocity += tforce*-40
        velocity += maxtforce*-40
        return velocity

    def jump(self):
        if self.moving == False:
            gravity_velocity = self.getVelocity()
            gravity_direction = Vector(self.position.x + gravity_velocity.x,self.position.y + gravity_velocity.y)
            winkel = math.atan2((self.position.y - gravity_direction.y) , (self.position.x - gravity_direction.x))
            walk_angle = math.degrees(winkel) + self.direction / 2.5
            self.velocity = Vector(math.cos(winkel),math.sin(winkel)) * self.jumpforce
            walk_angle = math.radians(walk_angle)
            walk_vector = Vector(math.cos(walk_angle),math.sin(walk_angle)) * self.jumpforce
            self.velocity.x += walk_vector.x
            self.velocity.y += walk_vector.y
            self.moving = True

    def move(self):
        image_array = self.terrain
        climb = 4 # Pixel
        gravity_velocity = self.getExpVelocity() * 1
        newpoint = Vector(self.x,self.y)
        # todo frametime
        for i in range(1):
            if self.moving == False:
                gravity_direction = Vector(self.position.x + gravity_velocity.x,self.position.y + gravity_velocity.y)
                winkel = math.atan2((self.position.y - gravity_direction.y) , (self.position.x - gravity_direction.x))
                walk_angle = winkel + math.radians(self.direction)
                walk_vector = Vector(round(math.cos(walk_angle)),round(math.sin(walk_angle))) * 1
                walk_vector_org = walk_vector
                winkel_vector = Vector(round(math.cos(winkel)),round(math.sin(winkel)))
                fall_vector = Vector(math.cos(winkel),math.sin(winkel))*-10 # fallhoehe
                collision = False
                for j in range(climb+1):
                    if (self.terrain.test(Vector(round(self.x) + walk_vector.x,round(self.y) + walk_vector.y))):
                        path = self.traceLine(int(self.x+walk_vector.x),int(self.y+walk_vector.y),int(self.x + walk_vector.x+ fall_vector.x),int(self.y + walk_vector.y + fall_vector.y))
                        j = 0
                        for j in range(0,len(path)):
                            points = path[j]
                            if (self.terrain.test(Vector(points[0],points[1])) == False):
                                collision = True
                                self.velocity = self.velocity * 0
                                newpoint = Vector(path[j-1][0],path[j-1][1])
                                break
                        if collision == False:
                            self.velocity = self.velocity * 0
                            newpoint = Vector(self.x + walk_vector_org.x,self.y + walk_vector_org.y)
                            self.moving = True
                            #print "MOVING ENGAGE"
                    else:
                        walk_vector = walk_vector + winkel_vector
                self.x = newpoint.x
                self.y = newpoint.y

    def shoot(self):
        self.selected_weapon.fire(self.power)

class KeyControledObject2():
    """
    Tastaturbelegung Player
    """
    def __init__(self):
        self.keys = {"a":False,"d":False,"w":False,"s":False,"j":False,"k":False," ":False}
        self.power = 0

    def processKeys(self):
        if self.keys["4"] == True:
            self.direction = 90
            self.move()
            winkel = self.angle - math.radians(90)
            self.velocity = self.velocity + Vector(math.cos(winkel),math.sin(winkel)) * 0.2
        if self.keys["6"] == True:
            self.direction = -90
            self.move()
            winkel = self.angle + math.radians(90)
            self.velocity = self.velocity + Vector(math.cos(winkel),math.sin(winkel)) * 0.2
        if self.keys["2"] == True:
            self.keys["2"] = False
            self.jump()
        if self.keys["k"] == True:
            self.keys["k"] = False

    # in ein anderes Objekt
    def getVelocity(self):
        velocity = Vector(0,0)
        if self.constant_forces:
            for force in self.constant_forces:
                velocity += force
        if self.dynamic_forces:
            for source in self.dynamic_forces:
                tforce = source.calculate_gravity(Vector(self.x,self.y))
                velocity += tforce*-40
        return velocity

    def getExpVelocity(self):
        maxtforce = Vector(0,0)
        velocity = Vector(0,0)
        if self.constant_forces:
            for force in self.constant_forces:
                velocity += force
        if self.dynamic_forces:
            for source in self.dynamic_forces:
                tforce = source.calculate_gravity(Vector(self.x,self.y))
                if tforce > maxtforce:
                    maxtforce = tforce
                #velocity += tforce*-40
        velocity += maxtforce*-40
        return velocity

    def jump(self):
        if self.moving == False:
            gravity_velocity = self.getVelocity()
            gravity_direction = Vector(self.position.x + gravity_velocity.x,self.position.y + gravity_velocity.y)
            winkel = math.atan2((self.position.y - gravity_direction.y) , (self.position.x - gravity_direction.x))
            walk_angle = math.degrees(winkel) + self.direction / 2.5
            self.velocity = Vector(math.cos(winkel),math.sin(winkel)) * self.jumpforce
            walk_angle = math.radians(walk_angle)
            walk_vector = Vector(math.cos(walk_angle),math.sin(walk_angle)) * self.jumpforce
            self.velocity.x += walk_vector.x
            self.velocity.y += walk_vector.y
            self.moving = True

    def move(self):
        image_array = self.terrain
        climb = 4 # Pixel
        gravity_velocity = self.getExpVelocity() * 1
        newpoint = Vector(self.x,self.y)
        # todo frametime
        for i in range(1):
            if self.moving == False:
                gravity_direction = Vector(self.position.x + gravity_velocity.x,self.position.y + gravity_velocity.y)
                winkel = math.atan2((self.position.y - gravity_direction.y) , (self.position.x - gravity_direction.x))
                walk_angle = winkel + math.radians(self.direction)
                walk_vector = Vector(round(math.cos(walk_angle)),round(math.sin(walk_angle))) * 1
                walk_vector_org = walk_vector
                winkel_vector = Vector(round(math.cos(winkel)),round(math.sin(winkel)))
                fall_vector = Vector(math.cos(winkel),math.sin(winkel))*-10 # fallhoehe
                collision = False
                for j in range(climb+1):
                    if (self.terrain.test(Vector(round(self.x) + walk_vector.x,round(self.y) + walk_vector.y))):
                        path = self.traceLine(int(self.x+walk_vector.x),int(self.y+walk_vector.y),int(self.x + walk_vector.x+ fall_vector.x),int(self.y + walk_vector.y + fall_vector.y))
                        j = 0
                        for j in range(0,len(path)):
                            points = path[j]
                            if (self.terrain.test(Vector(points[0],points[1])) == False):
                                collision = True
                                self.velocity = self.velocity * 0
                                newpoint = Vector(path[j-1][0],path[j-1][1])
                                break
                        if collision == False:
                            self.velocity = self.velocity * 0
                            newpoint = Vector(self.x + walk_vector_org.x,self.y + walk_vector_org.y)
                            self.moving = True
                            #print "MOVING ENGAGE"
                    else:
                        walk_vector = walk_vector + winkel_vector
                self.x = newpoint.x
                self.y = newpoint.y

    def shoot(self):
        self.selected_weapon.fire(self.power)


class TerrainController(TexturedObject):
    """
    Verwaltet das Spielfeld
    Rendern der Aenderungen via PIL
    """
    def __init__(self):
        self.offsetx = 0
        self.offsety = 0
        self.texture = 4
        self.texture = self.loadTexture("planets_bunt.bmp")
        self.masking = True
        self.mask = self.loadTexture("planets.bmp")
        self.image_array = self.generatePixelArray("planets.bmp")

        #print self.image_array
        self.unwalkable = (255,255,255)
        #self.ellipse()

    def generatePixelArray(self,mapfile):
        self.image_data = open(mapfile)
        return self.image_data.load()

    def ellipse(self,position):

        draw = ImageDraw.Draw(self.image_data)
        draw.ellipse((position.x-25,position.y-25,position.x+25,position.y+25), fill=(0,0,0))

        #image_data = image_data.rotate(45)
        #print "diese acht"
        ix = self.image_data.size[0]
        iy = self.image_data.size[1]
        self.image_data_raw = self.image_data.tostring("raw", "RGBX", 0, 1)

        glBindTexture(GL_TEXTURE_2D, self.texture)
        glPixelStorei(GL_UNPACK_ALIGNMENT,1)
        glTexImage2D(GL_TEXTURE_2D, 0, 3, ix, iy, 0, GL_RGBA, GL_UNSIGNED_BYTE, self.image_data_raw)
        glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP)
        glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP)
        glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT)
        glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT)
        glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST)
        glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST)
        #glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL)

        self.image_array = self.image_data.load()


    def center(self,objects):
        tmpXHigh = objects[0].x
        tmpYHigh = objects[0].y
        tmpXLow = objects[0].x
        tmpYLow = objects[0].y
        for object in objects:
            if (object.x > tmpXHigh):
                tmpXHigh = object.x
            if (object.y > tmpYHigh):
                tmpYHigh = object.y
            if (object.x < tmpXLow):
                tmpXLow = object.x
            if (object.y < tmpYLow):
                tmpYLow = object.y

        self.offsetx = ((tmpXLow + (tmpXHigh - tmpXLow) / 2) - 320) * -1
        self.offsety = ((tmpYLow + (tmpYHigh - tmpYLow) / 2) - 240) * -1

        #self.offsety = 0
        #self.offsetx = 0

        #print int(tmpXLow)
        #glOrtho( 0.0, 640.0 + tmpXHigh - tmpXLow, 0.0, 480.0 + tmpYHigh - tmpYLow, 1.0, 5.0);
        #glOrtho( tmpXLow, 640, tmpYLow, 480, 1.0, 5.0)
        #glOrtho( 0.0, 640, 0.0, 480, 1.0, 5.0)
        #glViewport(0,0,640,480)
        glMatrixMode(GL_PROJECTION)
        #glOrtho(-1.5 + zoom, 1.0 - zoom, -2.0 + zoom, 0.5 - zoom, -1.0, 3.5);
        zoom = -100
        xdistance = tmpXHigh - tmpXLow
        ydistance = tmpYHigh - tmpYLow
        
        zoomx = xdistance / 640 * -100
        zoomy = ydistance / 480 * -100
        print ydistance
        #tmpXLow - 100
        glOrtho( 0.0 + zoomx, 640 -zoomx, 0.0 + zoomy, 480 - zoomy, 1.0, 5.0)
        #glMatrixMode(GL_MODELVIEW)

    def getOffset(self):
        pass

    def test(self,position):
        if (position.x >= 0 and position.x < self.width and position.y >=0 and position.y < self.height):
            color = self.image_array[position.x,position.y]
            if color != self.unwalkable:
                return color
            else:
                return False
        else:
            return True

    def draw(self):
#        speed_scroll = 100
#        global starttime,endtime,fps,frametime
#
#
#        #print "loop"
#
#        while starttime == endtime:
#            endtime = time.clock()
#
#        frametime = endtime - starttime
#        starttime = endtime
#
#        fps = 1/frametime
#
#        frametime = 1

        #print fps

        global textures

        #print "terrain:",self.texture
        #self.offset -= 0.3

#        global image_array
#        global offset, factor
        #glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)
        #glLoadIdentity()					# Reset The View
        # Move Left 1.5 units and into the screen 6.0 units.
        glTranslatef(self.offsetx,self.offsety,0)

        glEnable(GL_TEXTURE_2D)
        #glDisable(GL_TEXTURE_2D)

            # Draw a square (quadrilateral)
        glBindTexture(GL_TEXTURE_2D, self.texture)
        glBegin(GL_QUADS)                   # Start drawing a 4 sided polygon
        #glColor3f(0.7, 0.7, 0.7)

        glTexCoord2f(0.0, 1.0);
        glVertex3f(0, self.height, -2)              # Top Left
        glTexCoord2f(1.0, 1.0);
        glVertex3f(self.width, self.height, -2)            # Top Right
        glTexCoord2f(1.0, 0.0);
        glVertex3f(self.width, 0, -2)              # Bottom Right
        glTexCoord2f(0.0, 0.0);
        glVertex3f(0, 0, -2)                # Bottom Left
        glEnd()                             # We are done with the polygon

        #glDisable(GL_TEXTURE_2D);


        # Move Right 3.0 units.
        #glTranslatef(200,220,0)

class Vector(object):
    def __init__(self, x=0.0,y=0.0):
        self.x = x
        self.y = y

    def __add__(self, o):
        self.x = self.x + o.x
        self.y = self.y + o.y
        return self

    def __mul__(self, o):
        self.x = self.x * o
        self.y = self.y * o
        return self

    def __gt__(self, o):
        if (abs(self.x) + abs (self.y) > abs(o.x) + abs (o.y)):
            return True
        else:
            return False

    def distance(self,o):
        return math.sqrt(((self.x -o.x)**2 + (self.y-o.y)**2))

    def greater(self,o):
        if ((self.x + self.y) > (o.x + o.y)):
            return True

    def norm(self):
        return math.sqrt(math.pow(self.x, 2)+math.pow(self.y, 2))

class GravitationalObject(BaseObject):
    def __init__(self, position, master, mymass):
        #self.position = myposition
        BaseObject.__init__(self,position, master)
        self.mass = mymass
        #print "GravitationalObject: ",self.position

    def update(self,dif):
        pass

    def draw(self):
        glDisable(GL_TEXTURE_2D)

        glPushMatrix()
        glTranslatef(self.x,self.y,0)
        glBegin(GL_POLYGON)                 # Start drawing a polygon
        glColor3f(1.0, 0.0, 0.0)
#        glVertex3f(self.x, self.y+5, 0.0)           # Top
#        glVertex3f(self.x+5, self.y-5, 0.0)          # Bottom Right
#        glVertex3f(self.x-5, self.y-5, 0.0)


        glVertex3f(0.0,5.0, 0.0)           # Top
        glVertex3f(5.0,-5.0, 0.0)          # Bottom Right
        glVertex3f(-5.0,-5.0, 0.0)

        glEnd()
        glPopMatrix()

    def calculate_gravity(self, position):
        distance = self.position.distance(position)
        gforce =  self.mass / distance
        # todo: besser!
        #angle = math.degrees(math.atan2((self.position.y - position.y) , (self.position.x - position.x)))
        angle = math.degrees(math.atan2((position.y - self.position.y) , (position.x - self.position.x)))
        angle = math.radians(angle)
        return Vector(math.cos(angle)*gforce,math.sin(angle)*gforce)

class MovingObject(BaseObject):
    def __init__(self, position, master, cforces = False, dforces = False, pulse = Vector(0,0)):
        BaseObject.__init__(self,position, master)
        self.surfaceColor = False
        self.pathLength = 0
        self.masking = False
        self.master = master
        self.angle = 0
        self.velocity = pulse
        self.constant_forces = cforces
        self.dynamic_forces = dforces
        self.bounce_count = 0
        self.old_angle = False
        self.moving = True
        self.rot = 0
        self.color = [random(),random(),random()]
        self.terrain = False
        self.path = ()

    def bounce(self,point_collision,point_last):
        t = self.master.terrain.image_array
        c = point_collision

        m0= {}
        m1= {}
        m2= {}
        m3= {}
        m4= {}
        m5= {}
        m6= {}
        m7= {}

        m0["k"] = (-1,+1)
        m0["z"] = 0
        m0["v"] = t[c[0]-1,c[1]+1]
        m1["k"] = (0,+1)
        m1["z"] = 1
        m1["v"] = t[c[0],c[1]+1]
        m2["k"] = (+1,+1)
        m2["z"] = 2
        m2["v"] = t[c[0]+1,c[1]+1]
        m3["k"] = (+1,0)
        m3["z"] = 3
        m3["v"] = t[c[0]+1,c[1]]
        m4["k"] = (+1,-1)
        m4["z"] = 4
        m4["v"] = t[c[0]+1,c[1]-1]
        m5["k"] = (0,-1)
        m5["z"] = 5
        m5["v"] = t[c[0],c[1]-1]
        m6["k"] = (-1,-1)
        m6["z"] = 6
        m6["v"] = t[c[0]-1,c[1]-1]
        m7["k"] = (-1,0)
        m7["z"] = 7
        m7["v"] = t[c[0]-1,c[1]]

        m = m0,m1,m2,m3,m4,m5,m6,m7

        summe = point_last[0] - point_collision[0],point_last[1] - point_collision[1]
        #print "point_last: ", point_last ,", point_collision: ", point_collision ,", summe: " ,summe

        if (summe == (0,0)):
            #print "summe (0,0)"
            return Vector(0,0) * 0

        for n in m:
            if n["k"] == summe:
                #print "DRIN"
                index = n["z"]
                #print "LAST: ", m[index]["z"]
                break

        stop = index + len(m) / 2
        if stop > len(m) - 1:
            stop = stop - len(m)

        #print "m-stop: ", m[stop]["k"]
        #print "len m ",len(m)
        #print "gegnueber, index: ", stop , index

        lefthit = False
        righthit = False
        for i in range(0,len(m)/2):
            #print "iteration: ", i
            if lefthit == False:
                left = index - i
                if left < 0:
                    left = left + (len(m))
                if m[left]["v"] == (255,255,255):
                    lefthit = m[left]["z"]

            if righthit == False:
                right = index + i
                if right > len(m) - 1:
                    right = right - (len(m)-1)
                if m[right]["v"] == (255,255,255):
                    righthit = m[right]["z"]
#            print "right: ",m[right]["z"]
#            print "left: ",m[left]["z"]

        #winkel = m[right]["k"]
        #winkel = math.atan2((self.position.y - gravity_direction.y) , (self.position.x - gravity_direction.x))
        winkel = math.atan2((m[righthit]["k"][1] - m[lefthit]["k"][1]) , (m[righthit]["k"][0] - m[lefthit]["k"][0]))

        mywinkel = math.atan2(self.y - (self.y+self.velocity.y) , self.x - (self.x+self.velocity.x) )

        mywinkel = math.atan2(self.y - (self.y+self.velocity.y) , self.x - (self.x+self.velocity.x) )
        #print "mywinkel: ",math.degrees(mywinkel)

#        left = Vector(-1,1)
#        right = Vector(1,-1)

        #terrainwinkel = math.atan2(righthit[1] - (lefthit[1]) , righthit[0] - (lefthit[0]) )
        terrainwinkel = math.atan2((m[lefthit]["k"][1] - m[righthit]["k"][1]) , (m[lefthit]["k"][0] - m[righthit]["k"][0]))
        #terrainwinkel = math.radians(225)
        #print "terrainwinkel: ",math.degrees(terrainwinkel)

        norm_terrainwinkel = terrainwinkel - math.radians(90)
        #print "norm_terrainwinkel: ",math.degrees(norm_terrainwinkel)

        new_winkel = norm_terrainwinkel + (norm_terrainwinkel - mywinkel)
        #print "new_winkel: ",math.degrees(new_winkel)

        return Vector(math.cos(new_winkel),math.sin(new_winkel)) * (self.velocity.norm() * 0.75)



    def traceLine(self,x,y,x2,y2):
        steep = 0
        coords = []
        dx = abs(x2 - x)
        if (x2 - x) > 0: sx = 1
        else: sx = -1
        dy = abs(y2 - y)
        if (y2 - y) > 0: sy = 1
        else: sy = -1
        if dy > dx:
            steep = 1
            x,y = y,x
            dx,dy = dy,dx
            sx,sy = sy,sx
        d = (2 * dy) - dx
        for i in range(0,dx):
            if steep: coords.append((y,x))
            else: coords.append((x,y))
            while d >= 0:
                y = y + sy
                d = d - (2 * dx)
            x = x + sx
            d = d + (2 * dy)
        coords.append((x2,y2))
        return coords

    def update(self):
        # kruecke!!
#        self.master.terrain.offsetx = (self.x - 320) * -1
#        self.master.terrain.offsety = (self.y - 240) * -1

        if self.constant_forces:
            for force in self.constant_forces:
                self.velocity += force
        if self.dynamic_forces:
            for source in self.dynamic_forces:
                tforce = source.calculate_gravity(Vector(self.x,self.y))
                self.velocity += tforce*-40

        if self.moving == True:
            self.obs = False
            self.angleDirection = math.atan2(self.y - (self.y+self.velocity.y) , self.x - (self.x+self.velocity.x) )
            self.path = self.traceLine(int(self.x),int(self.y),int(self.x + self.velocity.x),int(self.y + self.velocity.y))
            point_last = self.path[0]
            for point in self.path:
                self.pathLength = self.pathLength + 1
                test = self.terrain.test(Vector(point[0],point[1]))
                if (test == False):
                    self.pathLength = 0
                    self.moving = False
                    self.x = point_last[0]
                    self.y = point_last[1]
                    self.collision(Vector(point[0],point[1]),Vector(point_last[0],point_last[1]))
                    break
                else:
                    self.surfaceColor = test
                point_last = point
            # immer noch true nach collision?
            if self.moving == True:
                self.angle = math.atan2(self.y - (self.y+self.velocity.y) , self.x - (self.x+self.velocity.x) )
                self.x += self.velocity.x
                self.y += self.velocity.y


    def animate(self):
        glBindTexture(GL_TEXTURE_2D, texture_mytex)

    def draw(self):
        glPushMatrix()
        glTranslatef(self.x,self.y,0)
        glRotatef(math.degrees(self.angleDirection)-90,0,0,1)

        glEnable(GL_TEXTURE_2D)
        if (self.masking):
            glEnable(GL_BLEND)
            glBlendFunc(GL_DST_COLOR,GL_ZERO)
            glDisable(GL_DEPTH_TEST)
            glBindTexture(GL_TEXTURE_2D, self.mask)
            glBegin(GL_QUADS)
            glTexCoord2f(0.0, 1.0)
            glVertex3f(-15, +15, 2)
            glTexCoord2f(0.0, 0.0)
            glVertex3f(-15, -15, 2)
            glTexCoord2f(1.0, 0.0)
            glVertex3f(+15, -15, 2)
            glTexCoord2f(1.0, 1.0)
            glVertex3f(+15, +15, 2)
            glEnd()
            glBlendFunc(GL_ONE, GL_ONE)


        glBindTexture(GL_TEXTURE_2D, self.texture)
        glBegin(GL_QUADS)                       # Start drawing a 4 sided polygon
        glTexCoord2f(0.0, 1.0)
        glVertex3f(-15, +15, -2)     # Top Left
        glTexCoord2f(0.0, 0.0)
        glVertex3f(-15, -15, -2)     # Bottom Left
        glTexCoord2f(1.0, 0.0)
        glVertex3f(+15, -15, -2)     # Bottom Right
        glTexCoord2f(1.0, 1.0)
        glVertex3f(+15, +15, -2)     # Top Right
        glEnd()

        glEnable(GL_DEPTH_TEST)
        glDepthFunc(GL_LESS)

        glPopMatrix()


class Weaponset():
    def __init__(self):
        pass

class Weapon():
    def __init__(self,parent):
        self.angle = 0
        self.parent = parent

    def fire(self,power):
        angle = math.radians((self.parent.direction + self.parent.angle_aim)*(self.parent.direction/abs(self.parent.direction)))
        vector = Vector(math.cos(angle),math.sin(angle)) * power
        shot = ExplodingObject(Vector(self.parent.x,self.parent.y),self.parent.master,self.parent.constant_forces,self.parent.dynamic_forces,vector)
        shot.terrain = self.parent.terrain
        #print "hier: ", self.parent.master.objects
        self.parent.master.objects.append(shot)

class ExplodingObject(MovingObject):
    def __init__(self, parent, position, cforces = False, dforces = False, pulse = Vector(0,0)):
        #print "init-ex"
        self.colli = 0
        MovingObject.__init__(self, parent, position, cforces, dforces, pulse)
        self.texture = 2

    def collision(self,point_of_collision,point_last):
        if (self.colli < 5):
            self.velocity = self.bounce((point_of_collision.x,point_of_collision.y), (point_last.x,point_last.y))
            self.moving = True
            self.colli = self.colli + 1
        else:
            self.moving = False
            self.master.objects.remove(self)
            self.terrain.ellipse(Vector(self.x,self.y))
            self.position = Vector(self.x,self.y)
            for o in self.master.players:
                position_o = Vector(o.x,o.y)

                distance = self.position.distance(position_o)
                gforce =  50 / (distance + 1)
                # todo: besser!
                #angle = math.degrees(math.atan2((self.position.y - position.y) , (self.position.x - position.x)))
                angle = math.degrees(math.atan2((o.y - self.y) , (o.x - self.x)))
                #print "winkel: ", angle
                angle = math.radians(angle)

                if o != self:
                    #print "drin im velocity teil"
                    o.velocity = Vector(math.cos(angle),math.sin(angle))*gforce
                    o.moving = True
                    #print "type: ",instance(o)

        #print self.velocity.x,self.velocity.y
        #self.velocity = self.velocity * 0
        #self.moving = False



        #del self

class ParticleEmitter(BaseObject,TexturedObject):
    def __init__(self,position,master):
        BaseObject.__init__(self,position,master)
        self.particleCount = 100
        self.count = 2

        self.color = (0.0,0.0,0.0)

        self.texture = self.loadTexture("particle2.bmp")
        self.particles = list()
        for i in range(0,self.particleCount,1):
            pass


    def draw(self):

        glEnable(GL_TEXTURE_2D)

        #glEnable(GL_BLEND)
        #glClear(GL_COLOR_BUFFER_BIT )
        #glClearColor(0.0, 1.0, 0.0, 1.0)

        #glBlendFunc(GL_SRC_ALPHA,GL_ONE)
        glDisable(GL_DEPTH_TEST)
        glEnable(GL_BLEND)
        glBlendFunc(GL_SRC_ALPHA,GL_ONE)
        #glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA)
        glBindTexture(GL_TEXTURE_2D, self.texture)

        #glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_BLEND)
        #glEnable(GL_COLOR_MATERIAL)
        for particle in self.particles:
            particle.update()
            particle.draw()
        glDisable(GL_BLEND)
        glDisable(GL_TEXTURE_2D)
        glEnable(GL_DEPTH_TEST)
        glColor4f(1.0,1.0,1.0,1.0)

    def update(self,i):
        #self.x = self.master.x
        #self.y = self.master.y
        self.emitParticle(self.count)

    def emitParticle(self,count):
        for i in range(0,count,1):
            self.particles.append(Particle(Vector(self.master.x,self.master.y),self))

    def appendParticle(self,position):
        self.particles.append(Particle(position,self))


class Particle(BaseObject):
    def __init__(self,position,parent):
        BaseObject.__init__(self,position,parent)
        self.life = 1.0
        self.emitter = parent
        self.fx = -1
        self.fy = -1
        if (abs(self.emitter.master.velocity.x) > 0):
            self.fx = self.emitter.master.velocity.x / abs(self.emitter.master.velocity.x)
        if (abs(self.emitter.master.velocity.y) > 0):
            self.fy = self.emitter.master.velocity.y / abs(self.emitter.master.velocity.y)
        self.position.x = self.position.x + (random()) * 10
        self.position.y = self.position.y + (random()) * 10

    def update(self):
        self.life = self.life - 0.015
#        self.position.x = self.position.x + (random() * self.fx)
#        self.position.y = self.position.y + (random() * self.fy)
        if (self.life < 0):
            self.emitter.particles.remove(self)

    def draw(self):
        #glColor3f(0.9,0,0)
        #glColor4f(0.9,0.0,0.0,1.0)

#        glDisable(GL_TEXTURE_2D)
#        glBegin(GL_TRIANGLE_STRIP)
#        glVertex3f(self.x+5,self.y+5,0)
#        glVertex3f(self.x-5,self.y+5,0)
#        glVertex3f(self.x+5,self.y-5,0)
#        glVertex3f(self.x-5,self.y-5,0)
#        glEnd()
        #glEnable(GL_TEXTURE_2D)

        #glColor4f(0.3,0.6,1.0,self.life)

        #glColor4f(1.0,0.3,0.3,self.life)
        glColor4f(0.7,0.3,0.9,self.life)

        #glColor4f(self.emitter.color[0],self.emitter.color[1],self.emitter.color[2],self.life)


#        #glBlendFunc(GL_SRC_ALPHA,GL_ONE)
#        glBegin(GL_TRIANGLE_STRIP)
#        glTexCoord2d(1,1)
#        glVertex3f(self.x+5,self.y+5,-0.1)
#        glTexCoord2d(0,1)
#        glVertex3f(self.x-5,self.y+5,-0.1)
#        glTexCoord2d(1,0)
#        glVertex3f(self.x+5,self.y-5,-0.1)
#        glTexCoord2d(0,0)
#        glVertex3f(self.x-5,self.y-5,-0.1)
#        glEnd()

        glPushMatrix()
        glTranslatef(self.position.x,self.position.y,0)
        glBegin(GL_TRIANGLE_STRIP)
        glTexCoord2d(1,1)
        glVertex3f(+5,+5,2)
        glTexCoord2d(0,1)
        glVertex3f(-5,+5,2)
        glTexCoord2d(1,0)
        glVertex3f(+5,-5,2)
        glTexCoord2d(0,0)
        glVertex3f(-5,-5,2)
        glEnd()
        glPopMatrix()


class Character(MovingObject,KeyControledObject,TexturedObject):
    def __init__(self, position, master,cforces = False, dforces = False, pulse = Vector(0,0)):
        MovingObject.__init__(self, position, master, cforces, dforces, pulse)
        KeyControledObject.__init__(self)
        self.direction = -90
        self.jumpforce = 2.30
        self.angle_aim = 90
        self.selected_weapon = Weapon(self)
        self.masking = True
        self.texture = self.loadTexture("ship2.bmp")
        self.mask = self.loadTexture("ship2_mask.bmp")

        self.level = 0

    def collision(self,point_of_collision,point_last):
        self.velocity = self.velocity*0

        # retrace on collision
        velocity = self.getExpVelocity()
        path = self.traceLine(int(self.x),int(self.y),int(self.x + velocity.x),int(self.y + velocity.y))
        i = 0
        if len(path) > 2:
            i = i + 1
            points = path[1]
            if (self.terrain.test(Vector(points[0],points[1]))):
                self.moving = True



class SpaceGame():
    def __init__(self,map):
        self.terrain = map
        self.record = 0
        self.lastPath = 0
        #self.mc = parent
        self.players = list()
        self.objects = list()

        cforces = list()
        dforces = list()

        gravity = -0.1
        #angle_gravity = math.radians(90)
        angle_gravity = math.radians(90)
        force_gravity = Vector(math.cos(angle_gravity),math.sin(angle_gravity)) * gravity

        planet_one = GravitationalObject(Vector(340,220),self,0.2)

        self.colors = {
        True : -1,
        False : -1,
        (0,0,0) : -1,
        (255,255,255) : -1,
        (68,173,57) : 1,
        (163,255,187) : 2,
        (255,168,30) : 3,
        (129,104,255) : 4,
        (130,169,255) : 5,
        (255,102,226) : 6,
        (84,58,255) : 7,
        (147,247,255) : 8,
        (211,255,20) : 9,
        (255,183,84) : 10,
        (255,63,70) : 11,
        (252,255,114) : 12,
        (0,148,255) : 13,
        (255,252,81) : 14,
        (104,255,129) : 15,
        (255,0,220) : 16,
        (188,138,50) : 17,
        (99,0,145) : 18,
        (178,0,255) : 19
        }



        self.structures = list()

        self.structures.append({(9,10,11,8,4):1})
        self.structures.append({(2,3,4,5,6):2})
        self.structures.append({(16,17,18,19):3})
        self.structures.append({(11,15,12,10,13,14,12,11):4})
        self.structures.append({(11,12,14,13,10,12,15,11):4})


        self.sequenceIndex = self.buildSequenceIndex()

        #print self.structure




         #planets map:
        planet_1 = GravitationalObject(Vector(150,154),self,0.2)
        planet_2 = GravitationalObject(Vector(319,275),self,0.2)
        planet_3 = GravitationalObject(Vector(436,467),self,0.2)
        planet_4 = GravitationalObject(Vector(673,378),self,0.2)
        planet_5 = GravitationalObject(Vector(933,494),self,0.2)
        planet_6 = GravitationalObject(Vector(1047,217),self,0.2)
        planet_7 = GravitationalObject(Vector(1439,331),self,0.2)


        # surface-map
#        planet_1 = GravitationalObject(Vector(170,150),self,0.2)
#        planet_2 = GravitationalObject(Vector(269,437),self,0.2)
#        planet_3 = GravitationalObject(Vector(413,242),self,0.2)
#        planet_4 = GravitationalObject(Vector(578,456),self,0.2)
#        planet_5 = GravitationalObject(Vector(600,150),self,0.2)

        dforces.append(planet_1)
        dforces.append(planet_2)
        dforces.append(planet_3)
        dforces.append(planet_4)
        dforces.append(planet_5)
        dforces.append(planet_6)
        dforces.append(planet_7)



        #cforces.append(force_gravity)
        #dforces.append(planet_one)

        ## negative:
        #negative_planet = GravitationalObject(Vector(400,300),self,-0.2)
#        negative_planet = GravitationalObject(Vector(1065,1056),self,-0.5)
#        dforces.append(negative_planet)
#        self.objects.append(negative_planet)

        char = Character(Vector(600,400),self,cforces,dforces)
        keys.registerKeys(char,("a","d","j"))
        char.terrain = map

        char2 = Character(Vector(400,600),self,cforces,dforces)
        keys.registerKeys(char2,("4","6","0"))
        char2.terrain = map
        #char2 = Character(Vector(300,400),self,cforces,dforces)
        #char = Character(Vector(1000,1000),self,cforces,dforces)
       
        #char2.terrain = map

#        self.objects.append(planet_1)
#        self.objects.append(planet_2)
#        self.objects.append(planet_3)
#        self.objects.append(planet_4)
#        self.objects.append(planet_5)
#        self.objects.append(planet_6)
#        self.objects.append(planet_7)

        #cross = RelativePositionObject(char)

        #self.objects.append(cross)
        self.players.append(char)
        self.players.append(char2)
        
        keys.target = char
        #keys2.target = char2

        self.particleEmitter = ParticleEmitter(Vector(200,200),char)

        self.registerUpdate(self.particleEmitter)

        self.sequence = list()
        self.actColor = (0,0,0)
        self.sequenceFull = False



#        planet_1 = GravitationalObject(Vector(50,54),self,0.2)
#        planet_2 = GravitationalObject(Vector(219,175),self,0.2)
#        planet_3 = GravitationalObject(Vector(336,367),self,0.2)
#        planet_4 = GravitationalObject(Vector(573,278),self,0.2)
#        planet_5 = GravitationalObject(Vector(833,394),self,0.2)
#        planet_6 = GravitationalObject(Vector(947,117),self,0.2)
#        planet_7 = GravitationalObject(Vector(1339,231),self,0.2)


    def buildStructure(self,level):
        level = level + 1
        if (level < 6):
            structure = {}
            for index, color in enumerate(self.colors):
                    structure[index] = self.buildStructure(level)
            return structure
        return False


    def buildSequenceIndex(self):
        i = 0
        for sequence in self.structures:
            for index, data in sequence.iteritems():
                item = index[i]
                print item

    def registerUpdate(self,object):
        pass
        #self.objects.append(object)

    def loop(self):
        global fps


        if (self.lastPath > self.record):
            self.record = self.lastPath


        szTitle = "%d FPS, Letzter Pfad: %d, Rekord: %d" % (fps,self.lastPath,self.record);
        glutSetWindowTitle(szTitle)

        #self.terrain.draw()
        #char.processKeys()
        #char2.processKeys()

        self.terrain.center(self.players)
        self.terrain.draw()


        self.particleEmitter.update(100)
        self.particleEmitter.draw()

        for p in self.players:
            p.processKeys()
            if (self.actColor != p.surfaceColor and p.surfaceColor != (255,255,255)):
                color = self.colors[p.surfaceColor]
                self.actColor = p.surfaceColor
                if (color > 0):
                    self.sequence.append(Sequence(color,p.path))
                    if (self.sequenceFull == False):
                        if (len(self.sequence) > 9):
                            self.sequenceFull = True
                    else:
                        checker = self.sequence.pop(0)
                    for structure in self.structures:
                        check = self.danielRecurse(structure,0)
            p.update()
            p.draw()
        for o in self.objects:
            o.update()
            o.draw()

    def danielRecurse(self,structure,level):
        for index, data in structure.iteritems():
            if (level < len(index)):
                if (index[level] == self.sequence[len(self.sequence)-level-1].surfaceColor):
                    self.danielRecurse(structure,level + 1)
            else:
                print "COMPLETE"
                path = self.sequence[:len(index)]
                for obj in path:
                    for tuple in obj.position:
                        self.particleEmitter.appendParticle(Vector(tuple[0],tuple[1]))


class Sequence():
    def __init__(self,surfaceColor,position):
        self.surfaceColor = surfaceColor
        self.position = position

def main():
    global window

    glutInit(())
    glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE | GLUT_ALPHA | GLUT_DEPTH)

    glutInitWindowSize(640, 480)
    glutInitWindowPosition(0, 0)
    window = glutCreateWindow("Wormgame")

    glutDisplayFunc (DrawGLScene)
    glutIdleFunc(DrawGLScene)
    glutReshapeFunc(ReSizeGLScene)

    glutKeyboardFunc (keyPressed)
    glutKeyboardUpFunc(keyUp)

    InitGL(640, 480)
    glutMainLoop()

# A general OpenGL initialization function.  Sets all of the initial parameters.
def InitGL(Width, Height):				# We call this right after our OpenGL window is created.
    #global image_array
    global textures
    #print "init"

    global keys,mc,keys2

    keys = KeyController()
    keys2 = KeyController()
    mc = MatchController()
    mc.newMatch()

    #loadTexture("map_mask5.bmp",3)

    #do(4)

#    image_data = open("map_mask5.bmp")
#    draw = ImageDraw.Draw(image_data)
#    draw.ellipse((200,200,400,400), fill=128)
#    chanegTexture(image_data,4)

    #self.image_array = image_data.load()


    #glEnable(GL_TEXTURE_2D)
    #glColor4f(1.0,0.0,1.0,0.5)
#    glClearColor(0.0, 0.0, 0.0, 0.0)	# This Will Clear The Background Color To Black
#    glClearDepth(1.0)					# Enables Clearing Of The Depth Buffer

#    glDepthFunc(GL_LESS)				# The Type Of Depth Test To Do
#    glEnable(GL_DEPTH_TEST)				# Enables Depth Testing
    #glShadeModel(GL_SMOOTH)				# Enables Smooth Color Shading
    #glEnable(GL_TEXTURE_2D)
    #glMatrixMode(GL_PROJECTION)

    glShadeModel(GL_SMOOTH)
    glClearColor(0.0,0.0,0.0,0.0)
    glClearDepth(1.0)
    #glDisable(GL_DEPTH_TEST)
    #glEnable(GL_BLEND)
    #glBlendFunc(GL_SRC_ALPHA,GL_ONE)
    #glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA)
    glHint(GL_PERSPECTIVE_CORRECTION_HINT,GL_NICEST)
    glHint(GL_POINT_SMOOTH_HINT,GL_NICEST)
    glEnable(GL_TEXTURE_2D)

    glEnable(GL_DEPTH_TEST)
    glDepthFunc(GL_LESS)
    #glDepthFunc(GL_ALWAYS)

#    glShadeModel(GL_SMOOTH)
#    glClearColor(0.0,0.0,0.0,0.0)
#    glClearDepth(1.0);
#    glEnable(GL_BLEND)
#    glBlendFunc(GL_SRC_ALPHA,GL_ONE)
#    glDisable(GL_DEPTH_TEST)
#    glHint(GL_PERSPECTIVE_CORRECTION_HINT,GL_NICEST)
#    glHint(GL_POINT_SMOOTH_HINT,GL_NICEST)


    glMatrixMode(GL_MODELVIEW)

    #glLoadIdentity()					# Reset The Projection Matrix
                                        # Calculate The Aspect Ratio Of The Window
    #gluPerspective(45.0, float(Width)/float(Height), 0.1, 100.0)
    glOrtho( 0.0, 640.0, 0.0, 480.0, -1.0, 5.0);


def ReSizeGLScene(Width, Height):
    if Height == 0:						# Prevent A Divide By Zero If The Window Is Too Small
        Height = 1
    glViewport(0, 0, Width, Height)		# Reset The Current Viewport And Perspective Transformation
    glMatrixMode(GL_PROJECTION)
    glLoadIdentity()
    glOrtho( 0, 640, 0, 480, -1.0, 5.0);
    glMatrixMode(GL_MODELVIEW)

def DrawGLScene():
    global textures
    global starttime,endtime,fps,frametime
    global g_dwLastFPS,g_nFPS,g_nFrames

    while starttime == endtime:
        endtime = time.clock()

    frametime = frametime + endtime - starttime
    starttime = endtime
    fps = 1/frametime

    if frametime > 0.01:
    #if 1:
        frametime = 0

        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)

        glLoadIdentity()
#        szTitle = "%d FPS" % (fps);
#        glutSetWindowTitle(szTitle)

        mc.loop()
#        glPushMatrix()
#        glColor3f(255,255,130)
#        glRasterPos2i(10,40)
#	glutBitmapCharacter(GLUT_BITMAP_HELVETICA_18, 33)
#        glPopMatrix()

        #  since this is double buffered, swap the buffers to display what just got drawn.
        glutSwapBuffers()

def keyPressed(*args):
    keys.keyDown(args[0])

def keyUp(*args):
    keys.keyUp(args[0])



texId = 0
starttime = 0
endtime = 0
fps = 0
frametime = 0
window = 0


#app = ApplicationGL()

main()
